#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include "os_disk.h"
#include "os.h"
#include "cJSON.h"

// #define Cmd_FsSize(...)          "df -h | grep -i " #__VA_ARGS__ " | awk '{print $2}'"
// #define Cmd_FsUsed(...)          "df -h | grep -i " #__VA_ARGS__ " | awk '{print $3}'"
// #define Cmd_FsAvail(...)         "df -h | grep -i " #__VA_ARGS__ " | awk '{print $4}'"
// #define Cmd_FsUsePercent(...)    "df -h | grep -i " #__VA_ARGS__ " | awk '{print $5}'"
// #define Cmd_FsMountPoint(...)    "df -h | grep -i " #__VA_ARGS__ " | awk '{print $6}'"

struct __cfg_disk CfgDisk;
struct __os_filesystem_usage OsFsUsageList[FS_MAX];

int load_conf_filesystems(char* cfgfile)
{
	FILE* fp = NULL; 
	char* stream; long txtlen = 0;
	cJSON *json;
	if((fp=fopen(cfgfile, "r")) == NULL)	//尝试读文件
	{
		fprintf(stderr, "cJSON/> {ERROR} Config file '%s' load faild\n", cfgfile);
		return 1;
	}
	else
	{
		txtlen = fstr_alloc(fp, &stream);
		//printf("%s\n", stream);
		json = cJSON_Parse(stream);
		cJSON* Metrics = cJSON_GetObjectItem(json, "metrics");
		int iMetrics = cJSON_GetArraySize(Metrics);
		cJSON* Disk = cJSON_GetArrayItem(Metrics, 0);
		cJSON* Filesystems = cJSON_GetObjectItem(Disk, "filesystems");
		int iFilesystems = cJSON_GetArraySize(Filesystems);
		int i;
		for(i=0; i < iFilesystems; i++){
			strcpy(CfgDisk.fs[i], cJSON_GetArrayItem(Filesystems, i)->valuestring);
		}
		CfgDisk.samplesec = cJSON_GetObjectItem(Disk, "samplesec")->valueint;
		CfgDisk.fsN = i;

		cJSON_Delete(json);
		fstr_free(stream);
		fclose(fp); fp=NULL;
		fprintf(stderr, "cJSON/> {INFO} Config file '%s' load success.\n", cfgfile);
	}

	return 0;	
}


int filesystem_usage(int ProbeIdx, char* fsName, struct __os_filesystem_usage* OsFsUsage)
{
	FILE *fp;
	char TmpFileName[32];
	memset(TmpFileName, 0, sizeof(TmpFileName));
	strcpy(TmpFileName, TMP_FILE_DIR);
	random_string(TMP_FILENAME_LEN, 
		TmpFileName+strlen(TmpFileName), ProbeIdx);
	//printf("Temp filename ->> %s\n", TmpFileName);
	char CMD[256];
	strcpy(CMD, "df -h | grep ");strcat(CMD, fsName);strcat(CMD, " | awk '{print $2}'");
	//printf("%s\n", CMD);
	if((fp=popen(CMD, "r")) != NULL){
		if(fgets(OsFsUsage->Sz, sizeof(OsFsUsage->Sz), fp) != NULL){
			OsFsUsage->Sz[strlen(OsFsUsage->Sz)-1]='\0';
			//printf("%s", OsFsUsage->Sz);
		}
	}
		strcpy(CMD, "df -h | grep ");strcat(CMD, fsName);strcat(CMD, " | awk '{print $3}'");
	//printf("%s\n", CMD);
	if((fp=popen(CMD, "r")) != NULL){
		if(fgets(OsFsUsage->Used, sizeof(OsFsUsage->Used), fp) != NULL){
			OsFsUsage->Used[strlen(OsFsUsage->Used)-1]='\0';
			//printf("%s", OsFsUsage->Used);
		}
	}
		strcpy(CMD, "df -h | grep ");strcat(CMD, fsName);strcat(CMD, " | awk '{print $4}'");
	//printf("%s\n", CMD);
	if((fp=popen(CMD, "r")) != NULL){
		if(fgets(OsFsUsage->Avail, sizeof(OsFsUsage->Avail), fp) != NULL){
			OsFsUsage->Avail[strlen(OsFsUsage->Avail)-1]='\0';
			//printf("%s", OsFsUsage->Avail);
		}
	}
		strcpy(CMD, "df -h | grep ");strcat(CMD, fsName);strcat(CMD, " | awk '{print $5}'");
	//printf("%s\n", CMD);
	if((fp=popen(CMD, "r")) != NULL){
		if(fgets(OsFsUsage->UsePercent, sizeof(OsFsUsage->UsePercent), fp) != NULL){
			OsFsUsage->UsePercent[strlen(OsFsUsage->UsePercent)-1]='\0';
			//printf("%s", OsFsUsage->UsePercent);
		}
	}
		strcpy(CMD, "df -h | grep ");strcat(CMD, fsName);strcat(CMD, " | awk '{print $6}'");
	//printf("%s\n", CMD);
	if((fp=popen(CMD, "r")) != NULL){
		if(fgets(OsFsUsage->MountPoint, sizeof(OsFsUsage->MountPoint), fp) != NULL){
			OsFsUsage->MountPoint[strlen(OsFsUsage->MountPoint)-1]='\0';
			//printf("%s", OsFsUsage->MountPoint);
		}
	}

	pclose(fp);

	return 0;
}

void filesystem_usage_print(struct __os_filesystem_usage* OsFsUsage)
{
	printf("Filesystem Size: %s\n", OsFsUsage->Sz);
	printf("Filesystem Used: %s\n", OsFsUsage->Used);
	printf("Filesystem Avail: %s\n", OsFsUsage->Avail);
	printf("Filesystem UsePercent: %s\n", OsFsUsage->UsePercent);
	printf("Filesystem MountPoint: %s\n", OsFsUsage->MountPoint);

}

void probe_filesystem_usage(void)
{
	for(int i = 0; i < CfgDisk.fsN; i++){
		filesystem_usage(i, CfgDisk.fs[i], &OsFsUsageList[i]);
		filesystem_usage_print(&OsFsUsageList[i]);
	}
}

